var stage = new createjs.Stage('gameView');
createjs.Ticker.setFPS(60);
createjs.Ticker.addEventListener('tick', stage);

var gameView = new createjs.Container();
gameView.x = 50;
gameView.y = 50;
stage.addChild(gameView);

//坐标数组
var circleArr = [
	[],
	[],
	[],
	[],
	[],
	[],
	[],
	[],
	[]
];
var cirlen = circleArr.length;
//猫,可移动距离,每个方向可移动的下一个点
var curCat;
//记录待搜索的元素
var openArr = new Array();
//记录不再搜索的元素
var closeArr = new Array();
//边界元素集合
var endArr = new Array();

//定义移动状态
var MOVE_NONE = -1,
	MOVE_LEFT = 0,
	MOVE_LEFT_UP = 1,
	MOVE_RIGHT_UP = 2,
	MOVE_RIGHT = 3,
	MOVE_RIGHT_DOWN = 4,
	MOVE_LEFT_DOWN = 5;

//click事件
function clickCat(e) {
	if (e.target.getCircleType() == curCat.TYPE_UNSELECTED) {
		e.target.setCircleType(curCat.TYPE_SELECTED);
		//如果点到边界元素，则从边界集合中删除该元素
		if (e.target.iX == 0 || e.target.iX == 8 || e.target.iY == 0 || e.target.iY == 8) {
			endArr = arrayRemove(e.target, endArr);
		};
	}
	if (curCat.iX == 0 || curCat.iY == 0 || curCat.iX == (cirlen - 1) || curCat.iY == (cirlen - 1)) {
		alert('你输了呃！');
		return;
	}
	var nextPoint = 0;
	//循环边界元素寻找最短路径
	if (endArr.length > 0) {
		for (var i = 0; i < endArr.length; i++) {
			setMinPath(curCat, endArr[i]);
			initlize();
		}
		var path = lastPath(endArr);
		nextPoint = path[path.length - 1];
		// console.log(nextPoint);return;
	};

	//移动猫
	curCat.setCircleType(curCat.TYPE_UNSELECTED);
	curCat = nextPoint;
	curCat.setCircleType(curCat.TYPE_CURCAT);

}

//画出背景
function createCircle() {
	for (var iY = 0; iY < cirlen; iY++) {
		for (var iX = 0; iX < cirlen; iX++) {
			var o = new Circle();
			gameView.addChild(o);
			circleArr[iX][iY] = o;
			o.iX = iX;
			o.iY = iY;
			o.x = iY % 2 ? iX * 55 + 25 : iX * 55;
			o.y = iY * 55;
			if (iX == parseInt(cirlen / 2) && iY == parseInt(cirlen / 2)) {
				o.setCircleType(o.TYPE_CURCAT);
				curCat = o;
				openArr.push(o);
			}
			//添加随机选中
			if (Math.random() < 0.1 && iX != parseInt(cirlen / 2) && iY != parseInt(cirlen / 2)) {
				o.setCircleType(o.TYPE_SELECTED);
			}
			if (((o.iX == 0 && o.iY != 0 && o.iY != (cirlen-1)) || o.iX == (cirlen - 1) || o.iY == 0 || o.iY == (cirlen - 1)) && o.getCircleType() == o.TYPE_UNSELECTED) {
				endArr.push(o);
			};
			o.addEventListener('click', clickCat);
		}
	}
}
createCircle();

//除了边界元素，其他的都初始化
function initlize() {
	for (var i = 0; i < cirlen; i++) {
		if (i != 0 && i != (cirlen - 1)) {
			for (var y = 0; y < cirlen; y++) {
				if (y != 0 && y != (cirlen - 1)) {
					circleArr[i][y].init();
				};
			}
		}
	};
	openArr = [];
	closeArr = [];
}

//根据值删除数组中的元素，返回删除后的数组
function arrayRemove(o, arr) {
	if (arr.length > 0 && arr.length == 1) {
		return new Array();
	} else {
		for (var i = 0; i < arr.length; i++) {
			if (arr[i] == o) {
				arr.splice(i, 1);
				break;
			};
		}
		return arr;
	};
}

//取得中间元素相邻元素
function getNeighbor(o) {
	var sixArr = new Array();
	if ((o.iX - 1) >= 0)
		sixArr.push(circleArr[o.iX - 1][o.iY]);
	if ((o.iX - 1) >= 0 && (o.iY - 1) >= 0)
		sixArr.push(circleArr[o.iY % 2 ? o.iX : o.iX - 1][o.iY - 1]);
	if ((o.iX + 1) < cirlen && (o.iY - 1) >= 0)
		sixArr.push(circleArr[o.iY % 2 ? o.iX + 1 : o.iX][o.iY - 1]);
	if ((o.iX + 1) < cirlen)
		sixArr.push(circleArr[o.iX + 1][o.iY]);
	if ((o.iX + 1) < cirlen && (o.iY + 1) < cirlen)
		sixArr.push(circleArr[o.iY % 2 ? o.iX + 1 : o.iX][o.iY + 1]);
	if ((o.iX - 1) >= 0 && (o.iY + 1) < cirlen)
		sixArr.push(circleArr[o.iY % 2 ? o.iX : o.iX - 1][o.iY + 1]);
	return sixArr;
}
//是否添加到open列表
function addToOpen(p, o) {
	if (inArray(o, closeArr) == -1 && o.getCircleType() == curCat.TYPE_UNSELECTED) {
		// o.setCircleType(curCat.TYPE_TEST);
		openArr.push(o);
		o.PARENT = p;
		o.GVAL = getG(o);
	}
}

//计算G值
function getG(o) {
	var p = o.PARENT;
	return p.GVAL + 1;
}

//计算a到b的H值
function getH(a, b) {
	//如果a，b在同一条X轴
	if (a.iY == b.iY) {
		return Math.abs(b.iX - a.iX);
	}
	//如果a， b在同一条Y轴
	if (a.iX == b.iX) {
		return Math.abs(b.iY - a.iY);
	}
	var xp = 0,
		yp = 0;
	yp = Math.abs(b.iY - a.iY);

	var x = a.iX;
	var n = a.iY;
	//如果b.iX < a.iX
	if (b.iX < a.iX) {
		while (true) {
			x = n % 2 ? x : x - 1;
			if (a.iY > b.iY) {
				n--;
				if (n <= b.iY) break;
			} else {
				n++;
				if (n >= b.iY) break;
			}
		}
		xp = Math.abs(x - b.iX);
		return xp + yp;
	}
	//如果b.iX > a.iX
	else {
		while (true) {
			x = n % 2 ? x + 1 : x;
			if (a.iY > b.iY) {
				n--;
				if (n <= b.iY) break;
			} else {
				n++;
				if (n >= b.iY) break;
			}
		}
		xp = Math.abs(x - b.iX);
		return xp + yp;
	}
}

//找到下一个中心点
function findMiddle(mid, end) {

	//取得最小F值的元素
	if (openArr.constructor == Array && openArr.length > 0) {
		var minIndex = 0,
			minF = 0,
			tmpf = 0;
		for (var i = 0; i < openArr.length; i++) {
			//计算F值
			var f = openArr[i].GVAL + getH(openArr[i], end);
			if (i == 0) tmpf = f;
			if (f < tmpf) {
				midF = f;
				minIndex = i;
			}
		}
		mid = openArr[minIndex];
		mid.FVAL = minF;

		//把open中F最小的元素添加到close中
		closeArr.push(openArr[minIndex]);
		//从open中删除F值最小的
		openArr.splice(minIndex, 1);
	}

	//取得相邻元素
	var sixArr = getNeighbor(mid);
	for (var s = 0; s < sixArr.length; s++) {
		if (inArray(sixArr[s], openArr) == -1) {
			addToOpen(mid, sixArr[s]);
		}
	}

	return mid;
}

//求出最短路径数组
function getMinPathArr(end) {
	var p = end.PARENT;
	var pArr = [],
		i = 0;
	while (curCat != p && typeof(p) != 'undefined') {
		pArr[i] = p;
		p = p.PARENT;
		i++;
	}
	return pArr;
}

//计算猫到某个边界点的最短距离
function setMinPath(cat, end) {
	var mid = cat;
	while (true) {
		mid = findMiddle(mid, end);
		// mid.setCircleType(curCat.TYPE_MID);
		//结束循环
		if (inArray(end, openArr) >= 0 || openArr.length == 0) {
			var mp = getMinPathArr(end);
			end.MIN_PATH = mp;
			end.MIN_PATG_COUNT = mp.length;
			break;
		}
	}
}

//判断一个元素是否在某个数组中
function inArray(elem, array) {
	if (array.indexOf) {
		return array.indexOf(elem);
	}
	for (var i = 0, length = array.length; i < length; i++) {
		if (array[i] === elem) {
			return i;
		}
	}
	return -1;
}

//取得最终的最短路径，并初始化边界元素
function lastPath(end) {
	if (end.length <= 0) {
		return 0;
	};
	var minP = end[0].getMinPathCount();
	var minPath = 0;
	for (var i = 0; i < end.length; i++) {
		if (end[i].getMinPathCount() < minP) {
			minP = end[i].getMinPathCount();
			minPath = end[i].getMinPath();
		};
		if (minP < 3) {
			console.log(end[i]);
		};
		end[i].init();
	}
	return;
	return minPath;
}